package com.weilele.mvvm.view

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
import androidx.viewpager2.widget.ViewPager2
import com.weilele.mvvm.R
import com.weilele.mvvm.utils.activity.hadScrollToBottom
import com.weilele.mvvm.utils.activity.hadScrollToEnd
import com.weilele.mvvm.utils.activity.hadScrollToStart
import com.weilele.mvvm.utils.activity.hadScrollToTop
import com.weilele.mvvm.utils.safeGet

open class ScrollPagerView : ViewPager2Layout {
    val viewPager by lazy {
        ViewPager2(context).apply {
            layoutParams = LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT
            )
        }
    }
    private var contentView: View? = null
    private var direction: Int = DIRECTION_UP

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        context.obtainStyledAttributes(attrs, R.styleable.ScrollPagerView).also {
            direction = it.getInt(R.styleable.ScrollPagerView_scrollDirection, direction)
        }.recycle()
    }

    constructor(context: Context, direction: Int) : super(context) {
        this.direction = direction
    }


    private var downX = 0f
    private var downY = 0f
    override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
        val view = contentView
        val viewParent = view?.parent
        if (view is RecyclerView && viewParent != null && viewPager.orientation != ViewPager2.ORIENTATION_HORIZONTAL) {
            //解决嵌套recyclerView，嵌套滚动冲突
            when (event?.action) {
                MotionEvent.ACTION_DOWN -> {
                    downX = event.x
                    downY = event.y
                    viewParent.requestDisallowInterceptTouchEvent(true)
                }
                MotionEvent.ACTION_MOVE -> {
                    val offX = event.x - downX
                    val offY = event.y - downY
                    downX = event.x
                    downY = event.y
                    val manager = view.layoutManager
                    if (manager is LinearLayoutManager) {
                        if (viewPager.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
                            if ((offX < 0 && view.hadScrollToEnd()) || (offX > 0 && view.hadScrollToStart())) {
                                viewParent.requestDisallowInterceptTouchEvent(false)
                            } else {
                                viewParent.requestDisallowInterceptTouchEvent(true)
                            }
                        } else {
                            if ((offY < 0 && view.hadScrollToBottom()) || (offY > 0 && view.hadScrollToTop())) {
                                viewParent.requestDisallowInterceptTouchEvent(false)
                            } else {
                                viewParent.requestDisallowInterceptTouchEvent(true)
                            }
                        }
                    }
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    viewParent.requestDisallowInterceptTouchEvent(false)
                }
            }
        }
        return super.dispatchTouchEvent(event)
    }

    override fun onFinishInflate() {
        super.onFinishInflate()
        checkChild()
    }

    private fun checkChild() {
        when (childCount) {
            0 -> {
                //不做处理
            }
            1 -> {
                contentView = getChildAt(0)
                removeView(contentView)
                addView(viewPager)
                setAdapter()
            }
            else -> {
                throw IllegalArgumentException("只能包含一个子View")
            }
        }
    }

    private val viewPagerListener = object : ViewPager2.OnPageChangeCallback() {
        override fun onPageScrollStateChanged(state: Int) {
            super.onPageScrollStateChanged(state)
            if (state == ViewPager2.SCROLL_STATE_IDLE) {
                if (direction == DIRECTION_DOWN || direction == DIRECTION_END) {
                    if (viewPager.currentItem == 1) {
                        onDismissListener?.invoke(contentView)
                    }
                } else {
                    if (viewPager.currentItem == 0) {
                        onDismissListener?.invoke(contentView)
                    }
                }
            }
        }
    }

    private fun setAdapter() {
        viewPager.orientation = if (direction == DIRECTION_DOWN || direction == DIRECTION_UP) {
            ViewPager2.ORIENTATION_VERTICAL
        } else {
            ViewPager2.ORIENTATION_HORIZONTAL
        }
        viewPager.offscreenPageLimit = 2
        viewPager.adapter = Adapter()
        if (direction == DIRECTION_DOWN || direction == DIRECTION_END) {
            viewPager.setCurrentItem(1, false)
            setCurrentItem(0)
            viewPager.registerOnPageChangeCallback(viewPagerListener)
        } else {
            viewPager.setCurrentItem(0, false)
            setCurrentItem(1)
            viewPager.registerOnPageChangeCallback(viewPagerListener)
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        delayShow()
    }

    /**
     * 没有显示的时候，等合适时机再显示
     */
    private var needScrollPosition: Int? = null
    private fun setCurrentItem(position: Int) {
        if (!isAttachedToWindow) {
            needScrollPosition = position
            return
        }
        if (viewPager.currentItem == position) {
            return
        }
        viewPager.setCurrentItem(position, true)
        postDelayed({
            if (isAttachedToWindow && viewPager.currentItem != position) {
                setCurrentItem(position)
            }
        }, 500)
    }

    private fun delayShow() {
        val position = needScrollPosition ?: return
        needScrollPosition = null
        setCurrentItem(position)
    }

    private inner class Adapter : RecyclerView.Adapter<Holder>() {
        private val VIEW_TYPE_EMPTY = 1
        private val VIEW_TYPE_CONTENT = 2
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
            val view = when (viewType) {
                VIEW_TYPE_EMPTY -> {
                    FrameLayout(context).apply {
                        layoutParams = RecyclerView.LayoutParams(
                            RecyclerView.LayoutParams.MATCH_PARENT,
                            RecyclerView.LayoutParams.MATCH_PARENT,
                        )
                    }
                }
                VIEW_TYPE_CONTENT -> {
                    contentView!!.apply {
                        layoutParams = RecyclerView.LayoutParams(
                            RecyclerView.LayoutParams.MATCH_PARENT,
                            RecyclerView.LayoutParams.MATCH_PARENT,
                        )
                    }
                }
                else -> {
                    throw IllegalArgumentException("viewType 错误")
                }
            }
            return Holder(view)

        }

        override fun getItemViewType(position: Int): Int {
            return when (position) {
                0 -> {
                    if (direction == DIRECTION_START || direction == DIRECTION_UP) {
                        VIEW_TYPE_EMPTY
                    } else {
                        VIEW_TYPE_CONTENT
                    }
                }
                1 -> {
                    if (direction == DIRECTION_START || direction == DIRECTION_UP) {
                        VIEW_TYPE_CONTENT
                    } else {
                        VIEW_TYPE_EMPTY
                    }
                }
                else -> {
                    throw IllegalArgumentException("getItemCount只能为2")
                }
            }
        }

        override fun onBindViewHolder(holder: Holder, position: Int) {
            if (holder.itemView == contentView) {
                onBindViewListener?.invoke(holder.itemView)
            }
        }

        override fun getItemCount(): Int = 2
    }

    private inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView)

    /*************************************************************************/
    companion object {
        const val DIRECTION_UP = 1
        const val DIRECTION_DOWN = 2/*默认第一个为content*/
        const val DIRECTION_START = 3
        const val DIRECTION_END = 4/*默认第一个为content*/
    }

    var onBindViewListener: OnBindViewListener? = null
    var onDismissListener: OnDismissListener? = null

    fun dismiss() {
        post {
            if (direction == DIRECTION_DOWN || direction == DIRECTION_END) {
                viewPager.setCurrentItem(1, true)
            } else {
                viewPager.setCurrentItem(0, true)
            }
        }
    }

    fun show() {
        post {
            if (direction == DIRECTION_DOWN || direction == DIRECTION_END) {
                setCurrentItem(0)
            } else {
                setCurrentItem(1)
            }
        }
    }
}
typealias OnBindViewListener = (contentView: View) -> Unit
typealias OnDismissListener = (contentView: View?) -> Unit
